package com.lab.web.controller.biz;

import cn.hutool.core.date.DateUtil;
import com.lab.common.annotation.Log;
import com.lab.common.core.controller.BaseController;
import com.lab.common.core.domain.AjaxResult;
import com.lab.common.core.domain.entity.SysUser;
import com.lab.common.core.page.TableDataInfo;
import com.lab.common.enums.BusinessType;
import com.lab.common.utils.SendMail;
import com.lab.common.utils.StringUtils;
import com.lab.common.utils.poi.ExcelUtil;
import com.lab.system.domain.Lab;
import com.lab.system.domain.LabBorrow;
import com.lab.system.service.ILabBorrowService;
import com.lab.system.service.ILabService;
import com.lab.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.security.GeneralSecurityException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 实验室使用记录Controller
 *
 * @author cf
 * @date 2025-02-14
 */
@RestController
@RequestMapping("/system/labBorrow")
public class LabBorrowController extends BaseController {
    @Autowired
    private ILabBorrowService labBorrowService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ILabService labService;
    @Autowired
    private SendMail emailUtil;

    /**
     * 查询实验室使用记录列表
     */
    @GetMapping("/list")
    public TableDataInfo list(LabBorrow labBorrow) {
        startPage();
        List<LabBorrow> list = labBorrowService.selectLabBorrowList(labBorrow, getLoginUser());
        return getDataTable(list);
    }

    /**
     * 查询实验室使用记录列表
     */
    @GetMapping("/list/me")
    public TableDataInfo listMe(LabBorrow labBorrow) {
        startPage();
        labBorrow.setUserId(getUserId());
        List<LabBorrow> list = labBorrowService.selectLabBorrowList(labBorrow, getLoginUser());
        return getDataTable(list);
    }

    /**
     * 导出实验室使用记录列表
     */
    @Log(title = "实验室使用记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, LabBorrow labBorrow) {
        List<LabBorrow> list = labBorrowService.selectLabBorrowList(labBorrow, getLoginUser());
        ExcelUtil<LabBorrow> util = new ExcelUtil<LabBorrow>(LabBorrow.class);
        util.exportExcel(response, list, "实验室使用记录数据");
    }

    /**
     * 获取实验室使用记录详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(labBorrowService.selectLabBorrowById(id));
    }

    /**
     * 新增实验室使用记录
     */
    @Log(title = "实验室使用记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody LabBorrow labBorrow) {
        return toAjax(labBorrowService.insertLabBorrow(labBorrow, getUserId()));
    }

    /**
     * 修改实验室使用记录
     */
    @Log(title = "实验室使用记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody LabBorrow labBorrow) {
        return toAjax(labBorrowService.updateLabBorrow(labBorrow));
    }

    /**
     * 删除实验室使用记录
     */
    @Log(title = "实验室使用记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(labBorrowService.deleteLabBorrowByIds(ids));
    }

    /**
     * 取消实验室预约
     */
    @Log(title = "实验室使用记录", businessType = BusinessType.UPDATE)
    @PutMapping("/cancelLabBorrow/{id}")
    public AjaxResult cancelLabBorrow(@PathVariable("id") Long id) {
        Long userId = getUserId();
        LabBorrow labBorrow = labBorrowService.selectLabBorrowById(id);
        if (labBorrow == null) {
            return error("预约不存在");
        }
        if (!labBorrow.getUserId().equals(userId)) {
            return error("您没有权限取消该预约");
        }
        if (labBorrow.getStatus() != 0) {
            return error("当前状态不支持取消预约");
        }
        labBorrow.setStatus(3);

        // 查询lab的教师邮箱
        List<String> emails = new ArrayList<>();
        Lab lab = labService.selectLabById(labBorrow.getLabId());
        if (Objects.nonNull(lab)) {
            String teacherIds = lab.getTeacherIds();
            if (StringUtils.isNotBlank(teacherIds)) {
                List<Long> userIds = Arrays.stream(teacherIds.split(",")).collect(Collectors.toList()).stream().map(Long::valueOf).collect(Collectors.toList());
                List<SysUser> sysUsers = userService.queryByUserIds(userIds);
                emails = sysUsers.stream().map(SysUser::getEmail).filter(StringUtils::isNotBlank).collect(Collectors.toList());
            }
        }

        try {
            // 发送邮箱给实验室管理员
            for (String email : emails) {
                StringBuilder emailBuilder = new StringBuilder();
                emailBuilder.append("<p>您好，用户预约的实验室已被取消，请查收。</p>")
                        .append("<p>预约信息如下：</p>")
                        .append("<p>预约实验室：").append(lab.getLabName()).append("</p>")
                        .append("<p>预约时间：").append(DateUtil.format(labBorrow.getStartTime(),"yyyy-MM-dd HH:mm:ss")).append(" ~ ")
                        .append(DateUtil.format(labBorrow.getEndTime(), "yyyy-MM-dd HH:mm:ss")).append("</p>")
                        .append("<p>预约人：").append(labBorrow.getUserName()).append("</p>")
                        .append("<p>预约人备注：").append(StringUtils.isNotBlank(labBorrow.getRemark()) ? labBorrow.getRemark() : "无").append("</p>")
                        .append("<p>预约人状态：").append(labBorrow.getStatusDesc()).append("</p>")
                        .append("<p>预约人取消时间：").append(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")).append("</p>");
                emailUtil.sendMail(email, emailBuilder.toString());
            }
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        }
        return toAjax(labBorrowService.updateLabBorrow(labBorrow));
    }

    /**
     * 实验室开始使用时间记录
     */
    @Log(title = "实验室使用时间记录", businessType = BusinessType.UPDATE)
    @PutMapping("/useStart/{id}")
    public AjaxResult useStart(@PathVariable("id") Long id) {
        Long userId = getUserId();
        LabBorrow labBorrow = labBorrowService.selectLabBorrowById(id);
        if (labBorrow == null) {
            return error("预约不存在");
        }
        if (!labBorrow.getUserId().equals(userId)) {
            return error("您没有权限取消该预约");
        }
        if (labBorrow.getStatus() != 0) {
            return error("当前状态不支持使用签到");
        }
        labBorrow.setStatus(1);
        labBorrow.setUseStartTime(new Date());
        Lab lab = labService.selectLabById(labBorrow.getLabId());
        lab.setStatus(3L);
        labService.updateLab(lab);
        return toAjax(labBorrowService.updateLabBorrow(labBorrow));
    }


    /**
     * 实验室结束使用时间记录
     */
    @Log(title = "实验室使用时间记录", businessType = BusinessType.UPDATE)
    @PutMapping("/useEnd/{id}")
    public AjaxResult useEnd(@PathVariable("id") Long id) {
        Long userId = getUserId();
        LabBorrow labBorrow = labBorrowService.selectLabBorrowById(id);
        if (labBorrow == null) {
            return error("预约不存在");
        }
        if (!labBorrow.getUserId().equals(userId)) {
            return error("您没有权限取消该预约");
        }
        if (labBorrow.getStatus() != 1) {
            return error("当前状态不支持结束使用");
        }
        labBorrow.setStatus(2);
        labBorrow.setUseEndTime(new Date());
        Lab lab = labService.selectLabById(labBorrow.getLabId());
        lab.setStatus(1L);
        labService.updateLab(lab);
        return toAjax(labBorrowService.updateLabBorrow(labBorrow));
    }

    /**
     * 实验室预约审核
     */
    @PreAuthorize("@ss.hasPermi('system:labBorrow:edit')")
    @Log(title = "实验室预约审核", businessType = BusinessType.UPDATE)
    @PutMapping("/audit")
    public AjaxResult audit(@RequestParam("id") Long id, @RequestParam("audit") Integer audit) {
        Long userId = getUserId();
        LabBorrow labBorrow = labBorrowService.selectLabBorrowById(id);
        if (labBorrow == null) {
            return error("预约不存在");
        }
        if (labBorrow.getStatus() != 0) {
            return error("当前状态不支持审核");
        }
        // 判断audit,当audit已经审批完成不允许审批
        if (labBorrow.getAudit() == 2 || labBorrow.getAudit() == 3) {
            return error("当前状态已经审批完成");
        }
        // 判断audit,当audit已经审批完成不允许审批
        if (labBorrow.getAudit() == 1 && audit == 1) {
            return error("已经完成一级审批，无需重复审批");
        }
        labBorrow.setAudit(audit);
        return toAjax(labBorrowService.updateLabBorrow(labBorrow));
    }
}
